import type * as Koa from 'koa';

import Logger from '../utils/Logger';
import * as Enums from '../utils/Enums';
import { traceHeaderKey } from './traceHelper';

export default async (context: Koa.Context, next: Koa.Next) => {
  const { request, response } = context;
  if (request.method === Enums.HTTPMethods.OPTIONS) {
    await next();
    return;
  }
  const requestLogMessage: Record<string, any> = {
    type: 'access-request',
    access: `${request.method} - ${request.path}`,
    headers: filterHeaders(request.headers),
    requestId: request.headers[traceHeaderKey],
  };
  if (request.rawBody) {
    requestLogMessage.requestBody = request.rawBody;
  }
  Logger.info(requestLogMessage);
  await next();
  Logger.info({
    type: 'access-response',
    access: `${request.method} - ${request.path}`,
    status: response.status,
    requestId: request.headers[traceHeaderKey],
  });
};

export const valuableHeaderKeys = [
  'backend',
  'userId', 'accountId', 'regionId',
  'host', 'referer', 'user-agent',
];

export const filterHeaders = (
  headers: Koa.Request['headers'] | Koa.Response['headers'],
  filterKeys = valuableHeaderKeys,
): Record<string, string | string[] | number> => {
  const filteredHeaders: Record<string, string | string[] | number> = {};
  const lowerCaseFilterKeys = filterKeys.map((key) => key.toLowerCase());
  for (const key of Object.keys(headers)) {
    const headerValue = headers[key];
    if (lowerCaseFilterKeys.includes(key.toLowerCase()) && headerValue !== undefined) {
      filteredHeaders[key] = headerValue;
    }
  }
  return filteredHeaders;
};
